package com.appspot.codelab.docs.client.content.dialogs;

import com.appspot.codelab.docs.client.commands.SystemValidateProjectDetailsCommand;
import com.appspot.codelab.docs.client.events.CommandEvent;
import com.appspot.codelab.docs.client.events.ProjectSelectionEvent;
import com.appspot.codelab.docs.client.events.ProjectSelectionHandler;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.TextBox;

/**
 * A dialog window containing a form for selecting a project.
 */
public class DynamicProjectSelectionDialog extends DynamicFormDialog {

  /**
   * Contains form fields for selecting a project.
   */
  protected class ProjectSelectionFormContents extends FormContents {
	  
	protected TextBox projectName;
	protected Anchor projectUser;
	
    /**
     * Builds the project selection form.
     */
	@Override
	protected void buildForm() {
	  content.setWidth("600px");
	  projectUser = new Anchor(
	  DynamicProjectSelectionDialog.this.projectUser,
	      "http://code.google.com/u/" + DynamicProjectSelectionDialog.this.projectUser);
      projectUser.setTarget("_blank");
	  addField(projectUser, "Project User");
	  projectName = new TextBox();
	  projectName.setWidth("300px");
	  addField(projectName, "Project Name");
      submit.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
          if (projectName.getValue().equals("")) {
        	Window.alert("Project name is required.");
        	return;
          }
          CommandEvent.fire(
            new SystemValidateProjectDetailsCommand(
                projectName.getValue(),
                new AsyncCallback<Boolean>() {
					@Override
					public void onFailure(Throwable caught) {
					}
					@Override
					public void onSuccess(Boolean result) {
					  if (result) {
					    hide();
					    selectionHandler.onSelection(
					        new ProjectSelectionEvent(projectName.getValue()));
					  } else {
					    Window.alert("Project is not valid");
					  }
					}
                }
            )
          );
        }
      });
      cancel.addClickHandler(new ClickHandler(){
          public void onClick(ClickEvent event) {
            hide();
          }
      });
	}
  
    /**
     * Resets the form fields to their default values.
     */
    @Override
    public void resetForm() {
      this.projectUser.setText(DynamicProjectSelectionDialog.this.projectUser);
      this.projectUser.setHref(
          "http://code.google.com/u/" + DynamicProjectSelectionDialog.this.projectUser);
    }

  }

  protected static DynamicProjectSelectionDialog instance;
  
  /**
   * Retrieves the single instance of this class, using asynchronous instantiation.
   */
  public static DynamicProjectSelectionDialog get(
		String projectUser,
		ProjectSelectionHandler selectionHandler) {
    if (instance == null) {
      instance = new DynamicProjectSelectionDialog();
    }
    instance.projectUser = projectUser;
    instance.selectionHandler = selectionHandler;
    return instance;
  }
  
  protected String projectUser;
  protected ProjectSelectionHandler selectionHandler;
  
  /**
   * Constructs a dialog window containing a form for selecting a project.
   */
  public DynamicProjectSelectionDialog() {
    super("Project Details", true, "600px", null);
  }

  /**
   * Retrieves the dialog's contents asynchronously.
   * 
   * @param callback the callback carrying the content widget
   */
  @Override
  protected void getFormContents(final AsyncCallback<FormContents> callback) {
    GWT.runAsync(new RunAsyncCallback() {
		@Override
		public void onFailure(Throwable reason) {
		  callback.onFailure(reason);
		}
		@Override
		public void onSuccess() {
	      ProjectSelectionFormContents form = new ProjectSelectionFormContents();
	      form.resetForm();
		  callback.onSuccess(form);
		}
    });
  }

}
